package com.wodan.zhongjinjicang.common.orm.ibatis;

import com.wodan.zhongjinjicang.common.orm.metadata.MetaDataFactory;
import com.wodan.zhongjinjicang.common.orm.metadata.TableFieldMetaData;
import com.wodan.zhongjinjicang.common.orm.metadata.TableMetaData;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.reflection.wrapper.BeanWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



public class OrmBeanWrapper extends BeanWrapper {
	private static final Logger LOGGER = LoggerFactory.getLogger(OrmBeanWrapper.class);

	private Object object;
	private TableMetaData tableMetaData;

	public OrmBeanWrapper(MetaObject metaObject, Object object) {
		super(metaObject, object);
		this.object = object;

		this.tableMetaData = MetaDataFactory.createTableMetaData(object.getClass());
	}

	public Object get(PropertyTokenizer prop) {
		if (prop.getIndex() != null) {
			Object collection = resolveCollection(prop, object);
			return getCollectionValue(prop, collection);
		} else {
			String fieldName = prop.getName();
			TableFieldMetaData field = tableMetaData.getFieldByFieldName(fieldName);
			if (field != null) {
				return field.readFieldValue(object);
			} else {
				LOGGER.debug("类[" + tableMetaData.getTableClass() + "]表[" + tableMetaData.getTableName() + "]字段["
						+ fieldName + "]未找到映射关系");
				return super.get(prop);
			}
		}
	}

	public void set(PropertyTokenizer prop, Object value) {
		if (prop.getIndex() != null) {
			Object collection = resolveCollection(prop, object);
			setCollectionValue(prop, collection, value);
		} else {
			String name = prop.getName();
			TableFieldMetaData field = tableMetaData.getFieldByFieldName(name);
			if (field != null) {
				field.writeFieldValue(object, value);
				
			} else {
				LOGGER.debug("类[" + tableMetaData.getTableClass() + "]表[" + tableMetaData.getTableName() + "]字段[" + name
						+ "]未找到映射关系");
				super.set(prop, value);
			}
		}
	}

	public String findProperty(String name, boolean useCamelCaseMapping) {
		TableFieldMetaData field = tableMetaData.getFieldByColumnName(name);
		if (field == null) {
			return null;
		}
		return field.getFieldName();
	}

	public String[] getGetterNames() {
		throw new UnsupportedOperationException("未实现此方法，也无法复用父类方法，暂时抛异常");
	}

	public String[] getSetterNames() {
		throw new UnsupportedOperationException("未实现此方法，也无法复用父类方法，暂时抛异常");
	}

	public Class<?> getSetterType(String name) {
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
			if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
				TableFieldMetaData field = tableMetaData.getFieldByFieldName(name);
				return field.getFieldObjetClass();
			} else {
				return metaValue.getSetterType(prop.getChildren());
			}
		} else {
			TableFieldMetaData field = tableMetaData.getFieldByFieldName(name);
			return field.getFieldObjetClass();
		}
	}

	public Class<?> getGetterType(String name) {
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
			if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
				TableFieldMetaData field = tableMetaData.getFieldByFieldName(name);
				return field.getFieldObjetClass();
			} else {
				return metaValue.getGetterType(prop.getChildren());
			}
		} else {
			TableFieldMetaData field = tableMetaData.getFieldByFieldName(name);
			return field.getFieldObjetClass();
		}
	}

	public boolean hasSetter(String name) {
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			if (tableMetaData.isFieldNameExist(prop.getIndexedName())) {
				MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
				if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
					return tableMetaData.isFieldNameExist(name);
				} else {
					return metaValue.hasSetter(prop.getChildren());
				}
			} else {
				return false;
			}
		} else {
			return tableMetaData.isFieldNameExist(name);
		}
	}

	public boolean hasGetter(String name) {
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			if (tableMetaData.isFieldNameExist(prop.getIndexedName())) {
				MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
				if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
					return tableMetaData.isFieldNameExist(name);
				} else {
					return metaValue.hasGetter(prop.getChildren());
				}
			} else {
				return false;
			}
		} else {
			return tableMetaData.isFieldNameExist(name);
		}
	}
}
